/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.Arrays;

class AccessNsieve {
    public static final int SIEVE_COMMON_NUMBER = 10000;
    public static final int CURRENT_LOOP_COUNT = 3;
    public static final int MAX_LOOP_COUNT = 80;
    public static final int MS_CONVERSION_RATIO = 1000;

    public static String pad(int number, int width) {
        String s = Integer.toString(number);
        int prefixWidth = width - s.length();
        if (prefixWidth > 0) {
            for (int i = 1; i <= prefixWidth; i++) {
                s = " " + s;
            }
        }
        return s;
    }

    public static int nsieve(int m, int[] isPrime) {
        int count;

        for (int i = 2; i <= m; i++) {
            isPrime[i] = 1;
        }
        count = 0;

        for (int i = 2; i <= m; i++) {
            if (isPrime[i] == 1) {
                for (int k = i + i; k <= m; k += i) {
                    isPrime[k] = 0;
                }
                count++;
            }
        }
        return count;
    }

    public static int sieves() {
        int sum = 0;
        for (int i = 1; i <= AccessNsieve.CURRENT_LOOP_COUNT; i++) {
            // System.out.println("method sieve for loop i's value is-->" + i);
            // System.out.println("Before the nsieve called, sum's value is -->" + sum);
            int m = (1 << i) * AccessNsieve.SIEVE_COMMON_NUMBER;
            int[] flags = new int[m + 1];
            Arrays.fill(flags,0);
            sum += nsieve(m, flags);
            // System.out.println("After the nsieve called, sum's value is -->" + sum);
        }
        return sum;
    }
}

/*
 *@State
 *@Tags Jetstream2
 */
class Benchmark {
    public void run() {
        int result = AccessNsieve.sieves();
        int expected = 14302;
        if (result != expected) {
            System.out.println("ERROR: bad result: expected " + expected + " but got " + result);
        }
    }

    /*
     * @Benchmark
     */
    public void runIterationTime() {
        double start = (double) System.nanoTime() / 1_000_000;
        for (int i = 0; i < AccessNsieve.MAX_LOOP_COUNT; i++) {
            run();
        }
        double end = (double) System.nanoTime() / 1_000_000;
        System.out.println("access-nsieve: ms = " + (end - start));
    }

    public static void main(String[] args) {
        new Benchmark().runIterationTime();
    }
}